/**
 * regex-workbench: - Copyright (C) 2012 - Marcius da Silva da Fonseca
 *
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */
package br.msf.netbeans.regexworkbench;

import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.MenuSelectionManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;

/**
 * <p>Top component which displays the panel for RegEx testing.
 *
 * @author Marcius da Silva da Fonseca (sf.marcius@gmail.com)
 * @version 1.0
 */
@ConvertAsProperties(dtd = "-//br.msf.netbeans.regexworkbench//RegexPanel//EN", autostore = false)
@TopComponent.Description(preferredID = "RegexPanelTopComponent",
                          iconBase = "br/msf/netbeans/regexworkbench/regex.png",
                          persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "properties", openAtStartup = false) //rightSlidingSide
@ActionID(category = "Window", id = "br.msf.netbeans.regexworkbench.RegexPanelTopComponent")
@ActionReference(path = "Menu/Window" /* , position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_RegexPanelAction", preferredID = "RegexPanelTopComponent")
@Messages({"CTL_RegexPanelAction=Regex Workbench",
           "CTL_RegexPanelTopComponent=Regex Workbench",
           "HINT_RegexPanelTopComponent=A simple Regex tool."
})
public final class RegexPanelTopComponent extends TopComponent {

    private final Collection<Integer> selectedFlags;

    public RegexPanelTopComponent() {
        selectedFlags = new ArrayList<Integer>(7);
        initComponents();
        setName(Bundle.CTL_RegexPanelTopComponent());
        setToolTipText(Bundle.HINT_RegexPanelTopComponent());
        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
    }

    /**
     * <p>This method is called from within the constructor to initialize the form.
     * <p><strong>WARNING: Do NOT modify this code. The content of this method is always regenerated by the
     * Form Editor.</strong>
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jToolBar1 = new javax.swing.JToolBar();
        buttonGroup1 = new javax.swing.ButtonGroup();
        flagMenu = new javax.swing.JPopupMenu();
        canonEqMI = new javax.swing.JCheckBoxMenuItem();
        caseInsensitiveMI = new javax.swing.JCheckBoxMenuItem();
        commentsMI = new javax.swing.JCheckBoxMenuItem();
        dotAllMI = new javax.swing.JCheckBoxMenuItem();
        unixLinesMI = new javax.swing.JCheckBoxMenuItem();
        unicodeCaseMI = new javax.swing.JCheckBoxMenuItem();
        multilineMI = new javax.swing.JCheckBoxMenuItem();
        jPanel4 = new javax.swing.JPanel();
        invalidRegex = new javax.swing.JLabel();
        regexField = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        escapedRegex = new javax.swing.JTextField();
        jToolBar2 = new javax.swing.JToolBar();
        autoUpdateBtn = new javax.swing.JToggleButton();
        manualUpdateBtn = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        clearBtn = new javax.swing.JButton();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        findMode = new javax.swing.JToggleButton();
        matchMode = new javax.swing.JToggleButton();
        jSeparator3 = new javax.swing.JToolBar.Separator();
        flagsBtn = new javax.swing.JButton();
        textPane0 = new br.msf.netbeans.regexworkbench.SamplePane();
        textPane1 = new br.msf.netbeans.regexworkbench.SamplePane();
        textPane2 = new br.msf.netbeans.regexworkbench.SamplePane();
        textPane3 = new br.msf.netbeans.regexworkbench.SamplePane();

        jToolBar1.setRollover(true);

        org.openide.awt.Mnemonics.setLocalizedText(canonEqMI, "Pattern.CANON_EQ"); // NOI18N
        canonEqMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.canonEqMI.toolTipText"));
        canonEqMI.setUI(new StayOpenCheckBoxMenuItemUI());
        canonEqMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                canonEqMIActionPerformed(evt);
            }
        });
        flagMenu.add(canonEqMI);

        org.openide.awt.Mnemonics.setLocalizedText(caseInsensitiveMI, "Pattern.CASE_INSENSITIVE"); // NOI18N
        caseInsensitiveMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.caseInsensitiveMI.toolTipText"));
        caseInsensitiveMI.setUI(new StayOpenCheckBoxMenuItemUI());
        caseInsensitiveMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                caseInsensitiveMIActionPerformed(evt);
            }
        });
        flagMenu.add(caseInsensitiveMI);

        org.openide.awt.Mnemonics.setLocalizedText(commentsMI, "Pattern.COMMENTS"); // NOI18N
        commentsMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.commentsMI.toolTipText"));
        commentsMI.setUI(new StayOpenCheckBoxMenuItemUI());
        commentsMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                commentsMIActionPerformed(evt);
            }
        });
        flagMenu.add(commentsMI);

        org.openide.awt.Mnemonics.setLocalizedText(dotAllMI, "Pattern.DOTALL"); // NOI18N
        dotAllMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.dotAllMI.toolTipText"));
        dotAllMI.setUI(new StayOpenCheckBoxMenuItemUI());
        dotAllMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                dotAllMIActionPerformed(evt);
            }
        });
        flagMenu.add(dotAllMI);

        org.openide.awt.Mnemonics.setLocalizedText(unixLinesMI, "Pattern.UNIX_LINES"); // NOI18N
        unixLinesMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.unixLinesMI.toolTipText"));
        unixLinesMI.setUI(new StayOpenCheckBoxMenuItemUI());
        unixLinesMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unixLinesMIActionPerformed(evt);
            }
        });
        flagMenu.add(unixLinesMI);

        org.openide.awt.Mnemonics.setLocalizedText(unicodeCaseMI, "Pattern.UNICODE_CASE"); // NOI18N
        unicodeCaseMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.unicodeCaseMI.toolTipText"));
        unicodeCaseMI.setUI(new StayOpenCheckBoxMenuItemUI());
        unicodeCaseMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unicodeCaseMIActionPerformed(evt);
            }
        });
        flagMenu.add(unicodeCaseMI);

        org.openide.awt.Mnemonics.setLocalizedText(multilineMI, "Pattern.MULTILINE"); // NOI18N
        multilineMI.setToolTipText(org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.multilineMI.toolTipText"));
        multilineMI.setUI(new StayOpenCheckBoxMenuItemUI());
        multilineMI.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                multilineMIActionPerformed(evt);
            }
        });
        flagMenu.add(multilineMI);

        setMaximumSize(new java.awt.Dimension(320, 1080));

        invalidRegex.setForeground(new java.awt.Color(255, 51, 51));
        org.openide.awt.Mnemonics.setLocalizedText(invalidRegex, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.invalidRegex.text"));

        regexField.addKeyListener(new OnTheFlyListener());
        regexField.setFont(new java.awt.Font("Lucida Console", 0, 12)); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.jLabel1.text"));

        escapedRegex.setEditable(false);
        escapedRegex.setFont(new java.awt.Font("Lucida Console", 0, 12)); // NOI18N
        escapedRegex.setToolTipText("<html>\n<p>Java source-code String format.</p>\n<p>Copy it and paste on your source-code!</p>\n</html>");

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(regexField)
                    .addGroup(jPanel4Layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(invalidRegex)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addComponent(escapedRegex))
                .addContainerGap())
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel4Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(invalidRegex))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(regexField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(escapedRegex, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        invalidRegex.setVisible(false);

        jToolBar2.setFloatable(false);
        jToolBar2.setRollover(true);

        autoUpdateBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/br/msf/netbeans/regexworkbench/auto-refresh.png"))); // NOI18N
        autoUpdateBtn.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(autoUpdateBtn, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.autoUpdateBtn.text"));
        autoUpdateBtn.setFocusable(false);
        autoUpdateBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        autoUpdateBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(autoUpdateBtn);

        manualUpdateBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/br/msf/netbeans/regexworkbench/refresh.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(manualUpdateBtn, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.updateBtn.text"));
        manualUpdateBtn.setFocusable(false);
        manualUpdateBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        manualUpdateBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        manualUpdateBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                manualUpdateBtnActionPerformed(evt);
            }
        });
        jToolBar2.add(manualUpdateBtn);
        jToolBar2.add(jSeparator1);

        clearBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/br/msf/netbeans/regexworkbench/clear.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(clearBtn, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.clearBtn.text"));
        clearBtn.setFocusable(false);
        clearBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        clearBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        clearBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearBtnActionPerformed(evt);
            }
        });
        jToolBar2.add(clearBtn);
        jToolBar2.add(jSeparator2);

        buttonGroup1.add(findMode);
        findMode.setIcon(new javax.swing.ImageIcon(getClass().getResource("/br/msf/netbeans/regexworkbench/find.png"))); // NOI18N
        findMode.setSelected(true);
        org.openide.awt.Mnemonics.setLocalizedText(findMode, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.findMode.text"));
        findMode.setFocusable(false);
        findMode.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        findMode.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        findMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                findModeActionPerformed(evt);
            }
        });
        jToolBar2.add(findMode);

        buttonGroup1.add(matchMode);
        matchMode.setIcon(new javax.swing.ImageIcon(getClass().getResource("/br/msf/netbeans/regexworkbench/match.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(matchMode, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.matchMode.text"));
        matchMode.setFocusable(false);
        matchMode.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        matchMode.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        matchMode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                matchModeActionPerformed(evt);
            }
        });
        jToolBar2.add(matchMode);
        jToolBar2.add(jSeparator3);

        flagsBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/br/msf/netbeans/regexworkbench/flags.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(flagsBtn, org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, "RegexPanelTopComponent.flagsBtn.text"));
        flagsBtn.setFocusable(false);
        flagsBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        flagsBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        flagsBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                flagsBtnActionPerformed(evt);
            }
        });
        jToolBar2.add(flagsBtn);

        textPane0.addTextKeyListener(new OnTheFlyListener());

        textPane1.addTextKeyListener(new OnTheFlyListener());

        textPane2.addTextKeyListener(new OnTheFlyListener());

        textPane3.addTextKeyListener(new OnTheFlyListener());

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jToolBar2, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
            .addComponent(textPane0, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
            .addComponent(textPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
            .addComponent(textPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
            .addComponent(textPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(21, 21, 21)
                .addComponent(textPane0, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(textPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(textPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(textPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void flagsBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_flagsBtnActionPerformed
        if (flagMenu.isShowing()) {
            flagMenu.setVisible(false);
        } else {
            flagMenu.show(flagsBtn, 0, flagsBtn.getHeight());
        }
    }//GEN-LAST:event_flagsBtnActionPerformed

    private void canonEqMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_canonEqMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.CANON_EQ);
    }//GEN-LAST:event_canonEqMIActionPerformed

    private void caseInsensitiveMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseInsensitiveMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.CASE_INSENSITIVE);
    }//GEN-LAST:event_caseInsensitiveMIActionPerformed

    private void commentsMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_commentsMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.COMMENTS);
    }//GEN-LAST:event_commentsMIActionPerformed

    private void dotAllMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dotAllMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.DOTALL);
    }//GEN-LAST:event_dotAllMIActionPerformed

    private void unixLinesMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unixLinesMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.UNIX_LINES);
    }//GEN-LAST:event_unixLinesMIActionPerformed

    private void unicodeCaseMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unicodeCaseMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.UNICODE_CASE);
    }//GEN-LAST:event_unicodeCaseMIActionPerformed

    private void multilineMIActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_multilineMIActionPerformed
        updateFlag((JCheckBoxMenuItem) evt.getSource(), Pattern.MULTILINE);
    }//GEN-LAST:event_multilineMIActionPerformed

    private void findModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_findModeActionPerformed
        updateMatching();
    }//GEN-LAST:event_findModeActionPerformed

    private void matchModeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_matchModeActionPerformed
        updateMatching();
    }//GEN-LAST:event_matchModeActionPerformed

    private void manualUpdateBtnActionPerformed(java.awt.event.ActionEvent evt) {
        updateMatching();
    }

    private void clearBtnActionPerformed(java.awt.event.ActionEvent evt) {
        regexField.setText("");
        escapedRegex.setText("");
        textPane0.clear();
        textPane1.clear();
        textPane2.clear();
        textPane3.clear();
        updateMatching();
        regexField.requestFocusInWindow();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToggleButton autoUpdateBtn;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JCheckBoxMenuItem canonEqMI;
    private javax.swing.JCheckBoxMenuItem caseInsensitiveMI;
    private javax.swing.JButton clearBtn;
    private javax.swing.JCheckBoxMenuItem commentsMI;
    private javax.swing.JCheckBoxMenuItem dotAllMI;
    private javax.swing.JTextField escapedRegex;
    private javax.swing.JToggleButton findMode;
    private javax.swing.JPopupMenu flagMenu;
    private javax.swing.JButton flagsBtn;
    private javax.swing.JLabel invalidRegex;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JToolBar.Separator jSeparator3;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JToolBar jToolBar2;
    private javax.swing.JButton manualUpdateBtn;
    private javax.swing.JToggleButton matchMode;
    private javax.swing.JCheckBoxMenuItem multilineMI;
    private javax.swing.JTextField regexField;
    private br.msf.netbeans.regexworkbench.SamplePane textPane0;
    private br.msf.netbeans.regexworkbench.SamplePane textPane1;
    private br.msf.netbeans.regexworkbench.SamplePane textPane2;
    private br.msf.netbeans.regexworkbench.SamplePane textPane3;
    private javax.swing.JCheckBoxMenuItem unicodeCaseMI;
    private javax.swing.JCheckBoxMenuItem unixLinesMI;
    // End of variables declaration//GEN-END:variables

    @Override
    public void componentOpened() {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed() {
        // TODO add custom code on component closing
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }

    private void updateMatching() {
        try {
            textPane0.resetHighlight();
            textPane1.resetHighlight();
            textPane2.resetHighlight();
            textPane3.resetHighlight();
            invalidRegex.setVisible(false);
            String regex = RegexUtils.escapeControlChars(regexField.getText());
            escapedRegex.setText(RegexUtils.showControlChars(regex));
            if (!regex.isEmpty()) {
                Pattern pattern = getPattern(regex);
                if (findMode.isSelected()) {
                    textPane0.findPattern(pattern);
                    textPane1.findPattern(pattern);
                    textPane2.findPattern(pattern);
                    textPane3.findPattern(pattern);
                } else {
                    textPane0.matchPattern(pattern);
                    textPane1.matchPattern(pattern);
                    textPane2.matchPattern(pattern);
                    textPane3.matchPattern(pattern);
                }
            }
        } catch (Exception ex) {
            escapedRegex.setText("");
            invalidRegex.setVisible(true);
            Logger.getLogger(getClass().getName()).log(
                    Level.WARNING, getBundleString("RegexPanelTopComponent.invalidRegex.text"));
        }
    }

    private void updateFlag(final JCheckBoxMenuItem source, int patternFlag) {
        if (source.isSelected()) {
            selectedFlags.add(patternFlag);
        } else {
            selectedFlags.remove(patternFlag);
        }
        if (autoUpdateBtn.isSelected()) {
            updateMatching();
        }
    }

    private Pattern getPattern(final String regex) {
        int flags = 0;
        for (Integer flag : selectedFlags) {
            flags = flags | flag;
        }
        return Pattern.compile(regex, flags);
    }

    private String getBundleString(String key) {
        return org.openide.util.NbBundle.getMessage(RegexPanelTopComponent.class, key);
    }

    class OnTheFlyListener extends java.awt.event.KeyAdapter {

        @Override
        public void keyReleased(java.awt.event.KeyEvent evt) {
            if (autoUpdateBtn.isSelected()) {
                updateMatching();
            }
        }
    };

    static class StayOpenCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI {

        @Override
        protected void doClick(MenuSelectionManager msm) {
            menuItem.doClick(0);
        }

        public static ComponentUI createUI(JComponent c) {
            return new StayOpenCheckBoxMenuItemUI();
        }
    }
}
